﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Objects.DataClasses;
using Fujitsu.JiraAnalysis.JiraRPC;
using Fujitsu.JiraAnalysis.DAL;
using Fujitsu.JiraAnalysis.Common;
using Fujitsu.JiraAnalysis.TrackingSystemAdapter;

namespace Fujitsu.JiraAnalysis.ReplicationService.Synchronize
{
    class ProjectVersionUpdate : DbObjectUpdateBase
    {
        private VersionStorage versionStorage = new VersionStorage();

        public ProjectVersionUpdate(ITrackSystemInfo adapter, int projectId, string projectKey, string projectName)
            : base(adapter, projectId, projectKey, projectName)
        { }

        protected override IEnumerable<AbstractRemoteEntity> GetRemoteEntities(string projectKey)
        {
            return Adapter.GetProjectVersions(projectKey);
        }

        protected override EntityObject FindMatchInDb(int projectId, AbstractRemoteEntity remoteEntity)
        {
            return versionStorage.GetVersion(projectId, (remoteEntity as RemoteVersion).id);
        }

        protected override void UpdateEntityObject(EntityObject dbEntityObject, AbstractRemoteEntity remoteEntity)
        {
            var dbVersion = dbEntityObject as DAL.Version;
            var jiraVersion = remoteEntity as RemoteVersion;

            logInfo.AppendLine(string.Format("Project '{0}' -> updated version '{1}', updated fields are", Name, dbVersion.Name));

            var isVersionEdited =
               UpdateEntityObjectField<string>(dbVersion, "Name", dbVersion.Name, jiraVersion.name)
             | UpdateEntityObjectField<bool>(dbVersion, "IsReleased", dbVersion.IsReleased, jiraVersion.released)
             | UpdateEntityObjectField<bool>(dbVersion, "IsArchived", dbVersion.IsArchived, jiraVersion.archived)
             | UpdateEntityObjectField<DateTime?>(dbVersion, "ReleaseDate", dbVersion.ReleaseDate, jiraVersion.releaseDate);

            if (isVersionEdited)
            {
                versionStorage.UpdateVersion(dbVersion);
                EventLogger.CreateInstance(eventLog).LogWrite(logInfo.ToString());
            }

            logInfo.Clear();
        }

        protected override void AddEntityObjectToDb(int projectId, AbstractRemoteEntity remoteEntityToBeAdded)
        {
            var remoteVersionToBeAdded = remoteEntityToBeAdded as RemoteVersion;
            var dbVersion = new DAL.Version
            {
                JiraVersionID = remoteVersionToBeAdded.id,
                ProjectID = projectId,
                Name = remoteVersionToBeAdded.name,
                IsReleased = remoteVersionToBeAdded.released,
                IsArchived = remoteVersionToBeAdded.archived,
                ReleaseDate = remoteVersionToBeAdded.releaseDate
            };

            if (versionStorage.AddVersion(dbVersion) != null)
            {
                EventLogger.CreateInstance(eventLog).LogWrite(string.Format("Added version '{0}' to project '{1}'", dbVersion.Name, Name));
            }
        }

        protected override IEnumerable<int> GetToBeDeletedList(int projectId, IEnumerable<AbstractRemoteEntity> remoteEntities)
        {
            var jiraVersionIds = remoteEntities.Select(remoteEntity => remoteEntity.id).ToList();
            return versionStorage.GetVersionsToBeDeleted(projectId, jiraVersionIds);
        }

        protected override void DeleteEntityObject(int dbEntityObjectId)
        {
            versionStorage.DeleteVersion(dbEntityObjectId);
        }
    }
}
